package com.dongdongqiang.daogenerator.handler.impl;

import com.dongdongqiang.daogenerator.exception.DDQException;
import com.dongdongqiang.daogenerator.handler.IUpdateHandler;
import com.dongdongqiang.daogenerator.pojo.TableColumn;
import com.dongdongqiang.daogenerator.pojo.TableMeta;
import com.dongdongqiang.daogenerator.sqlbuilder.UpdateSQLBuilder;
import com.dongdongqiang.daogenerator.statement.IUpdatePrepareStatementSetter;
import com.dongdongqiang.daogenerator.tablemetabuilder.TableMetaBuilderImpl;

import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

/**
 * Created by ZZB on 2017/10/19.
 */
public class UpdateHandlerImpl implements IUpdateHandler {
    private UpdateSQLBuilder updateSQLBuilder;
    private IUpdatePrepareStatementSetter updatePrepareStatementSetter;

    public UpdateHandlerImpl(UpdateSQLBuilder updateSQLBuilder, IUpdatePrepareStatementSetter updatePrepareStatementSetter) {
        this.updateSQLBuilder = updateSQLBuilder;
        this.updatePrepareStatementSetter = updatePrepareStatementSetter;
    }

    @Override
    public int update(Object o, Connection connection) throws DDQException {
        TableMeta tableMeta = TableMetaBuilderImpl.obtainByObject(o);
        String updateSQL = updateSQLBuilder.buildUpdateSQL(tableMeta);
        if(updateSQL == null) return 0;
        try {
            PreparedStatement preparedStatement = connection.prepareStatement(updateSQL);
            updatePrepareStatementSetter.setInPrepareStatement(preparedStatement, tableMeta, o);
            return preparedStatement.executeUpdate();
        } catch (SQLException | InvocationTargetException | NoSuchMethodException | IllegalAccessException | NoSuchFieldException e) {
            throw new DDQException(e);
        }
    }

    @Override
    public int[]  updateList(List<?> objects, Connection connection) throws DDQException {
        TableMeta tableMeta = TableMetaBuilderImpl.obtainByObject(objects.get(0));
        String updateSQL = updateSQLBuilder.buildUpdateSQL(tableMeta);
        if(updateSQL == null) return new int[]{0};
        try {
            PreparedStatement preparedStatement = connection.prepareStatement(updateSQL);
            updatePrepareStatementSetter.setBatchInPrepareStatement(preparedStatement, tableMeta, objects);
            return preparedStatement.executeBatch();
        } catch (SQLException | NoSuchMethodException | IllegalAccessException | NoSuchFieldException | InvocationTargetException e) {
            throw new DDQException(e);
        }
    }

    @Override
    public int updateField(Object pk, Class<?> tClass, String updateField, Object value, Connection connection) throws DDQException {
        TableMeta tableMeta = TableMetaBuilderImpl.obtainByClass(tClass);
        TableColumn tableColumn = TableMetaBuilderImpl.obtainByFieldName(tClass, updateField);
        if(tableColumn != null){
            updateField = tableColumn.getColumnName();
        }
        String updateSQL = updateSQLBuilder.buildUpdateFieldSQL(tableMeta,updateField,value,pk);
        if(updateSQL == null) return 0;
        try {
            PreparedStatement preparedStatement = connection.prepareStatement(updateSQL);
            preparedStatement.setObject(1,value);
            preparedStatement.setObject(2,pk);
            return preparedStatement.executeUpdate();
        } catch (SQLException e) {
            throw new DDQException(e);
        }
    }

    @Override
    public int updateListField(List<?> pks, Class<?> tClass, String updateField, Object value, Connection connection) throws DDQException {
        TableMeta tableMeta = TableMetaBuilderImpl.obtainByClass(tClass);
        TableColumn tableColumn = TableMetaBuilderImpl.obtainByFieldName(tClass, updateField);
        if(tableColumn != null){
            updateField = tableColumn.getColumnName();
        }
        String updateSQL = updateSQLBuilder.buildUpdateListFieldSQL(tableMeta,updateField,value,pks);
        if(updateSQL == null) return 0;
        try {
            PreparedStatement preparedStatement = connection.prepareStatement(updateSQL);
            preparedStatement.setObject(1,value);
            for (int i = 0; i < pks.size(); i++) {
                preparedStatement.setObject(i+2,pks.get(i));
            }
            return preparedStatement.executeUpdate();
        } catch (SQLException e) {
            throw new DDQException(e);
        }
    }
}
